# !/usr/bin/env python
# -*- coding: utf-8 -*-
# -*- Python version: 2.7.x -*-

import time
import datetime
from chitchatSettings import ChitchatDatabase
from chitchatLogging import ChitchatLogger
from pymongo.errors import * 

# Initiate MongoDB connection and logger
ccDb = ChitchatDatabase()
mongoConn = ccDb.ccMongo()
mongoLogger = ChitchatLogger("mongoLog")

def get_date():
    """
    Return a legal date used in database.
    @return     Legal date, e.g. "20161019".
    """
    return datetime.datetime.now().strftime("%Y%m%d")

def get_chatid(uid1, uid2):
    """ 
    Get chat ID from user ids.
    @param
        uid1 uid2       User id, non-negative integer less than 100,000.
    @return             Corresponding chat id.
    """
    if uid1 < uid2 :
       return "C" + str(uid1).rjust(5, '0') + str(uid2).rjust(5, '0')
    else:
       return "C" + str(uid2).rjust(5, '0') + str(uid1).rjust(5, '0')

def add_message(uid1, uid2, msg, date, timestamp):
    """ 
    Add a message from uid1 to uid2.
    @param
        uid1 uid2       Legal user ids.
        msg             Message content in utf-8 encoding.
        timestamp       Unix timestamp, use time.time() to get one.
    @format             A single message will be formatted to JSON like:
                            {"from" : uid,
                            "text" : msg,
                            "time" : UNIX_Timestamp}
    @return             Return 0 on success.
                        Return -1 on database exceptions.
    """
    chatid = get_chatid(uid1, uid2)
    message = {
        "from" : uid1,
        "text" : msg,
        "timestamp" : timestamp
    }
    try:
        # Send to history.
        mongoConn.chitchat.chat.update_one({"chatid" : chatid, "date" : date}, 
                                {"$push": {"messages": message}}, upsert = True)
        # Send to new messages' queue.
        mongoConn.chitchat.newmsg.insert({"to" : uid2, "timestamp" : timestamp, "message": message})
    except ConnectionFailure as _Ecnfail:
        mongoLogger.log.error(_Ecnfail)
    except OperationFailure as _Eopfail:
        mongoLogger.log.error(_Eopfail)
    except Exception as _Eall:
        mongoLogger.log.error(_Eall)
        return -1
    return 0

def add_link(uid1, uid2, url, title, content, timestamp, date):
    """ 
    Add a link preview sent from uid1 to uid2.
    @param
        uid1 uid2       Legal user ids.
        url             URL found in the message.
        title           URL page title.
        content         URL content preview.
        timestamp       Timestamp of the message containing the link.
    @format             Link should be like:
                            {"from" : uid1,
                            "url" : url,
                            "title" : title,
                            "content" : content,
                            "time" : timestamp
                            }
    @return             Return 0 on success.
                        Return -1 on database exceptions.
    """
    chatid = get_chatid(uid1, uid2)
    to = uid2
    link = {
        "from" : uid1,
        "url" : url,
        "title" : title,
        "content" : content,
        "timestamp" : timestamp
    }
    try:
        # Send to history.
        mongoConn.chitchat.chat.update_one({"chatid" : chatid, "date" : date}, 
                                {"$push": {"extra": link}}, upsert = True)
        # Send link to new messages' queue.
        mongoConn.chitchat.newmsg.insert({"to" : uid2, "timestamp" : timestamp, "message" : link})
    except Exception as _Eall:
        mongoLogger.log.error(_Eall)
        return -1
    return 0

def fetch_new(uid, fetch_time):
    """
    Fetch new message(s) for user uid before time fetch_time and remove
    them from database.
    @param
        uid         Legal user ID.
        fetch_time  Timestamp. New messages sent befrom fetch_time
                    will be fetched.
    @return         Return a Mongo cursor on success.
                    Return 0 if found no new message.
                    Return -1 if any exceptions occured.
    """
    try:
        res = mongoConn.chitchat.newmsg.find({"to" : uid,
                                        "timestamp":{"$lt":fetch_time}})
    except Exception as _Eall:
        mongoLogger.log.error(_Eall)
        return -1
    return res

def fetch_history(uid1, uid2, date):
    """ 
    Fetch chat history between two users on specific date.
    @param
        uid1 uid2       Legal user ids.
        date            A legal date on format 'MMDDYYYY', e.g. '20161010'.
    @return             JSON formatted chat history:
                            {"chatid" : chat_channel_id,
                            "date" : date,
                            "messages" : [msg1, msg2, ...],
                            "extra" : [link1, link2, ...]}
                            Section "extra" stores URL perview info.
                        If not found, return None.
                        Return -1 on database exceptions.
    """
    chatid = get_chatid(uid1, uid2)
    try:
        return mongoConn.chitchat.chat.find_one({"chatid" : chatid, "date" : date})
    except Exception as _Eall:
        mongoLogger.log.error(_Eall)
        return -1
